package cn.iocoder.yudao.module.member.agency.controller.app;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.framework.business.basic.enums.TimeRangeTypeEnum;
import cn.iocoder.yudao.framework.business.basic.pojo.vo.UserSimpleVO;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.api.brokerage.agency.BrokerageAgencyApi;
import cn.iocoder.yudao.module.api.brokerage.agency.vo.AgencyBrokerageMoneyTrendVO;
import cn.iocoder.yudao.module.api.brokerage.agency.vo.AgencyBrokerageSummaryVO;
import cn.iocoder.yudao.module.api.brokerage.user.BrokerageUserApi;
import cn.iocoder.yudao.module.api.pay.wallet.PayWalletApi;
import cn.iocoder.yudao.module.member.agency.dal.dataobject.AgencyUserDO;
import cn.iocoder.yudao.module.member.agency.service.AppAgencyUserService;
import cn.iocoder.yudao.module.member.agency.vo.AppAgencyCenterRespVO;
import cn.iocoder.yudao.module.member.agency.vo.AppAgencyUserVO;
import cn.iocoder.yudao.module.member.agency.vo.AppBonusMoneyChartRespVO;
import cn.iocoder.yudao.module.member.user.dal.dataobject.MemberUserDO;
import cn.iocoder.yudao.module.member.user.service.MemberUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Resource;
import jakarta.annotation.security.PermitAll;
import jakarta.validation.constraints.NotNull;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

@Tag(name = "用户 App - 招商人员中心")
@RestController
@RequestMapping("/member/agency-user")
@Validated
public class AppAgencyUserController {

    @Resource
    private AppAgencyUserService appAgencyUserService;
    @Resource
    private MemberUserService memberUserService;

    @Resource
    private BrokerageUserApi brokerageUserApi;
    @Resource
    private BrokerageAgencyApi brokerageAgencyApi;
    @Resource
    private PayWalletApi payWalletApi;

    @GetMapping("/center")
    @Operation(summary = "获得招商中心数据汇总")
    @PreAuthorize("@mm.isAgency()")
    public CommonResult<AppAgencyCenterRespVO> getMyCenter() {
        Long userId = getLoginUserId();
        AppAgencyCenterRespVO respVO = new AppAgencyCenterRespVO();
        MemberUserDO user = memberUserService.getUser(userId);
        respVO.setUser(BeanUtils.toBean(user, UserSimpleVO.class));
        AgencyUserDO agencyUserDO = appAgencyUserService.getOrCreate(userId);
        respVO.setAgency(BeanUtils.toBean(agencyUserDO, AppAgencyUserVO.class));
        respVO.setInviteUserCount(brokerageUserApi.getFatherCount(userId));
        AgencyBrokerageSummaryVO merchantSummaryRespDTO = brokerageAgencyApi.getSummary(userId);
        respVO.setInviteMerchantCount(merchantSummaryRespDTO.getInviteMerchantCount());
        respVO.setFreezingBonusMoney(merchantSummaryRespDTO.getFreezingBonusMoney());
        respVO.setTodayUnfreezeBonusMoney(merchantSummaryRespDTO.getTodayUnfreezeBonusMoney());
        respVO.setTotalUnfreezeBonusMoney(merchantSummaryRespDTO.getTotalUnfreezeBonusMoney());
        respVO.setCashMoney(payWalletApi.getOrCreateWallet(UserTypeEnum.MEMBER.getValue(), userId).getMoney());
        // 默认查询最近7天的佣金趋势
        LocalDateTime endTime = LocalDateTime.now();
        List<AgencyBrokerageMoneyTrendVO> trend = brokerageAgencyApi.getBonusMoneyTrend(userId, endTime.minusDays(TimeRangeTypeEnum.WEEK.getValue()), endTime);
        respVO.setBonusMoneyTrend(trend);
        respVO.setBonusMoneyChart(toChartRespVO(TimeRangeTypeEnum.WEEK.getValue(), trend));
        return success(respVO);
    }

    @GetMapping("/get-money-trend")
    @Operation(summary = "获得已结算佣金趋势")
    @Parameter(name = "days", description = "天数", required = true, example = "7")
    @PreAuthorize("@mm.isAgency()")
    public CommonResult<List<AgencyBrokerageMoneyTrendVO>> getMoneyTrend(@RequestParam("days") Integer days) {
        List<AgencyBrokerageMoneyTrendVO> list = getBrokerageBonusTrend(days);
        return success(list);
    }


    @GetMapping("/get-money-trend-v2")
    @Operation(summary = "获得已结算佣金趋势(ECharts)")
    @Parameter(name = "days", description = "天数", required = true, example = "7")
    @PreAuthorize("@mm.isAgency()")
    public CommonResult<AppBonusMoneyChartRespVO> getMoneyTrendV2(@RequestParam("days") Integer days) {
        List<AgencyBrokerageMoneyTrendVO> list = getBrokerageBonusTrend(days);
        return success(toChartRespVO(days, list));
    }

    @Nonnull
    private AppBonusMoneyChartRespVO toChartRespVO(@NotNull Integer days, List<AgencyBrokerageMoneyTrendVO> list) {
        AppBonusMoneyChartRespVO respVO = new AppBonusMoneyChartRespVO();
        if (CollUtil.isEmpty(list)) {
            respVO.setDates(Collections.emptyList());
            respVO.setCategories(Collections.emptyList());
            respVO.setSeries(Collections.emptyList());
            return respVO;
        }
        respVO.setDates(list.stream()
                .map(AgencyBrokerageMoneyTrendVO::getDate)
                .map(date -> DateUtil.format(date.atStartOfDay(), "yyyy-MM-dd"))
                .toList());
        respVO.setCategories(list.stream()
                .map(AgencyBrokerageMoneyTrendVO::getDate)
                .map(date -> DateUtil.format(date.atStartOfDay(), "MM/dd"))
                .toList());
        respVO.setCategories(reduceCategories(days, respVO.getCategories()));
        AppBonusMoneyChartRespVO.SeriesDTO seriesDTO = new AppBonusMoneyChartRespVO.SeriesDTO();
        seriesDTO.setName("近" + days + "天收益趋势");
        seriesDTO.setData(list.stream()
                .map(AgencyBrokerageMoneyTrendVO::getMoneyYuan)
                .map(String::valueOf)
                .toList());
        respVO.setSeries(Collections.singletonList(seriesDTO));
        return respVO;
    }

    @Nonnull
    private List<String> reduceCategories(Integer days, List<String> categories) {
        // 移动端屏幕较小，横轴只适合展示3-5个日期，以4个为宜，中间一些日期用空串占位
        int offset;
        if (days <= TimeRangeTypeEnum.WEEK.getValue()) {
            offset = 2;
            // 7天，0、2、4、6
        } else if (days <= TimeRangeTypeEnum.MONTH_HALF.getValue()) {
            offset = 5;
            // 15天，0、5、10、15
        } else if (days <= TimeRangeTypeEnum.MONTH.getValue()) {
            offset = 9;
            // 30天，0、9、18、27
        } else if (days <= TimeRangeTypeEnum.QUARTER.getValue()) {
            offset = 27;
            // 90天，0、27、54、71
        } else if (days <= TimeRangeTypeEnum.YEAR_HALF.getValue()) {
            offset = 54;
            // 180天，0、54、108、162
        } else if (days <= TimeRangeTypeEnum.YEAR.getValue()) {
            offset = 108;
            // 365天，0、108、216、324
        } else {
            offset = 216;
            // 365天，0、216、432、648
        }
        List<String> newCategories = new ArrayList<>(categories.size());
        for (int i = 0, n = categories.size(); i < n; i++) {
            if (i % offset != 0) {
                newCategories.add("");
            } else {
                newCategories.add(categories.get(i));
            }
        }
        return newCategories;
    }

    private List<AgencyBrokerageMoneyTrendVO> getBrokerageBonusTrend(@Nonnull Integer days) {
        Long userId = getLoginUserId();
        LocalDateTime endTime = LocalDateTime.now();
        LocalDateTime beginTime = endTime.minusDays(days);
        return brokerageAgencyApi.getBonusMoneyTrend(userId, beginTime, endTime);
    }

    @GetMapping("/my")
    @Operation(summary = "获得我的身份详情")
    @PreAuthorize("@mm.isAgency()")
    public CommonResult<AppAgencyUserVO> getMyDetail() {
        AgencyUserDO agencyUserDO = appAgencyUserService.getOrCreate(getLoginUserId());
        AppAgencyUserVO respVO = BeanUtils.toBean(agencyUserDO, AppAgencyUserVO.class);
        return success(respVO);
    }

    @GetMapping("/get-user-simple")
    @Operation(summary = "获得用户简单信息")
    @Parameter(name = "agencyId", description = "招商人员编号", required = true, example = "1024")
    @PermitAll
    public CommonResult<UserSimpleVO> getUserSimple(@RequestParam("agencyId") Long agencyId) {
        AppAgencyUserVO respVO = appAgencyUserService.getDetail(agencyId);
        if (respVO == null || respVO.getUserId() == null || respVO.getUserId() <= 0) {
            return success(null);
        }
        MemberUserDO user = memberUserService.getUser(respVO.getUserId());
        return success(BeanUtils.toBean(user, UserSimpleVO.class));
    }

}